{
  LW Meshes -- LightWave Geometry Services

  This unit contains the declarations for globals for accessing
  common geometric information.

  Based on lwmeshes.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}


unit LW_Meshes;

{$mode objfpc}{$H+}

interface

uses
  LW_Types;

const
  LWMESHITER_POLYGON = 1;
  LWMESHITER_POINT   = 2;

  // LWMeshEvent
  LWMESHEVNT_DESTROY = 0;

  // updated June 21, 2005 (edge functions added).
  LWOBJECTFUNCS_GLOBAL = 'Scene Objects 7';

type
  {
    Meshes are composed of points, edges, and polygons given by their internal
    ID reference.
  }

  PPPLWPnt  = ^PPLWPnt  ;
  PPLWPnt   = ^PLWPnt   ;
  PLWPnt    = ^TLWPnt   ;
  TLWPnt    = record end;

  PPPLWEdge = ^PPLWEdge;
  PPLWEdge  = ^PLWEdge;
  PLWEdge   = ^TLWEdge;
  TLWEdge   = record end;

  PPPLWPol = ^PPLWPol;
  PPLWPol  = ^PLWPol;
  PLWPol   = ^TLWPol;
  TLWPol   = record end;

  {
    Scan callbacks allow the client to traverse the elements of the
    mesh and get information about each one.
  }
  TLWPntScanFunc  = function (Data    : Pointer;
                              Point   : PLWPnt ) : SizeUInt;
  TLWPolScanFunc  = function (Data    : Pointer;
                              Polygon : PLWPol ) : SizeUInt;
  TLWEdgeScanFunc = function (Data    : Pointer;
                              Edge    : PLWEdge) : SizeUInt;

  {
    A mesh iterator enumerates all the mesh elements of a certain
    type.
  }
  PLWMeshIterator  = Pointer;

  PLWMeshInfo      = ^TLWMeshInfo;

  TLWMeshEvent     = Integer;

  TLWMeshEventFunc = function (Data      : Pointer     ;
                               Mesh      : PLWMeshInfo ;
                               Event     : TLWMeshEvent;
                               EventData : Pointer     ) : Integer;

  {
    A LWMeshInfo is an allocated object that allows a mesh to be examined
    through a set of query callbacks.

    Priv         private data for the mesh info implementation.  Hands off!

    Destroy      destroy the mesh when done.  A mesh should only be freed
                 by the client that created it.

    NumPoints
    NumPolygons
                 these functions return the size of the mesh as a count of
                 its points and polygons.

    ScanPoints
    ScanPolygons
                 iterate through elements in the mesh.  The scan function
                 callback is called for each element in the mesh.  If the
                 callback returns non-zero, the iteration stops and the
                 value is returned.

    PntBasePos   return the base position of a point.  This is the position
                 of the point at rest in the basic object coordinate system.

    PntOtherPos  return an alternate position for the point.  This many be
                 the same as the base position or it may be the position of
                 the point after some transformation.  The nature of the
                 alternate position depends on how the mesh info was created.

    PntVLookup   selects a vmap for reading vectors.  The vmap is given by
                 an ID code for the type and a name string.  The function
                 returns a pointer that may be used to select this same vmap
                 again quickly, or null for none.

    PntVSelect   selects a vmap for reading vectors.  The vmap is given by
                 the pointer returned from pntVLookup above.  The function
                 returns the dimension of the vmap.

    PntVGet      reads the vector value of the selected vmap for the given
                 point.  The vmap can be set using either of the two
                 functions above.  The vector must at least be as large as
                 the dimension of the vmap.  The function returns true if
                 the point is mapped.

    PntVPGet     just like the above, but reads the vector value of the
                 selected vmap for the given point and polygon.

    PolType      returns the type of a polygon as an LWPOLTYPE_* code.

    PolSize      returns the number of vertices that the polygon has.

    PolVertex    returns the point ID for the given vertex of the polygon.
                 Vertices are indexed starting from zero.

    PolTag       returns the tag string of the given type associated with the
                 polygon.  A null string pointer means that the polygon does
                 not have a tag of that type.

    PolFlags     returns the polygon flags, matching those used by the MeshEdit
                 polygon info structure in modeler.

    PntPolsNum   returns the number of polygons connected to the point

    PntPols      returns the count of client provided LWPolIDs array filled
                 in up to maxElements size.
  }
  TLWMeshInfo = record
    Priv                : Pointer;

    Destroy             : procedure (      MeshInfo     : PLWMeshInfo    ) ;

    NumPoints           : function  (      MeshInfo     : PLWMeshInfo    ) : Integer        ;
    NumPolygons         : function  (      MeshInfo     : PLWMeshInfo    ) : Integer        ;

    ScanPoints          : function  (      MeshInfo     : PLWMeshInfo    ;
                                           PntScanFunc  : TLWPntScanFunc ;
                                           Data         : Pointer        ) : SizeUInt       ;
    ScanPolys           : function  (      MeshInfo     : PLWMeshInfo    ;
                                           PolScanFunc  : TLWPolScanFunc ;
                                           Data         : Pointer        ) : SizeUInt       ;

    PntBasePos          : procedure (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Pos          : TLWFVector     ) ;
    PntOtherPos         : procedure (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Pos          : TLWFVector     ) ;
    PntVLookup          : function  (      MeshInfo     : PLWMeshInfo    ;
                                           ID           : TLWID          ;
                                     const Name         : PChar          ) : Pointer        ;
    PntVSelect          : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Data         : Pointer        ) : Integer        ;
    PntVGet             : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Vector       : PSingle        ) : Integer        ;

    PolType             : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ) : TLWID           ;
    PolSize             : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ) : Integer        ;
    PolVertex           : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                           Index        : Integer        ) : PLWPnt         ;
    PolTag              : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                           ID           : TLWID          ) : PChar          ;

    PntVPGet            : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Polygon      : PLWPol         ;
                                           Vector       : PSingle        ) : Integer        ;
    PolFlags            : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ) : UInt32         ;

    PntVIDGet           : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Vector       : PSingle        ;
                                           Data         : Pointer        ) : Integer        ;
    PntVPIDGet          : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Point        : PLWPnt         ;
                                           Polygon      : PLWPol         ;
                                           Vector       : PSingle        ;
                                           Data         : Pointer        ) : Integer        ;

    PolTypeFlags        : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ) : Integer        ;

    PolBaseNormal       : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                       out Normal       : TLWFVector     ) : Integer        ;
    PolOtherNormal      : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                       out Normal       : TLWFVector     ) : Integer        ;
    PntBaseNormal       : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                           Point        : PLWPnt         ;
                                       out Normal       : TLWFVector     ) : Integer        ;
    PntOtherNormal      : function  (      MeshInfo     : PLWMeshInfo    ;
                                           Polygon      : PLWPol         ;
                                           Point        : PLWPnt         ;
                                       out Normal       : TLWFVector     ) : Integer        ;

    CreateMeshIterator  : function  (      MeshInfo     : PLWMeshInfo    ;
                                           IteratorType : Integer        ) : PLWMeshIterator;
    DestroyMeshIterator : procedure (      MeshInfo     : PLWMeshInfo    ;
                                           MeshIterator : PLWMeshIterator) ;
    IterateMesh         : function  (      MeshInfo     : PLWMeshInfo    ;
                                           MeshIterator : PLWMeshIterator) : Pointer        ;
    ResetMeshIterator   : procedure (      MeshInfo     : PLWMeshInfo    ;
                                           MeshIterator : PLWMeshIterator) ;

    {
      Mesh event callbacks were added in 9.2.1
    }
    SetMeshEvent        : function  (      MeshInfo     : PLWMeshInfo     ;
                                           EventFunc    : TLWMeshEventFunc;
                                           Data         : Pointer         ) : Integer        ;

    {
      A multithreading-friendly version of pntVLookup. Unlike pntVLookup this does
      not set the vmap which pntVGet and pntVPGet read from.
    }
    PntVIDLookup        : function  (      MeshInfo     : PLWMeshInfo     ;
                                           ID           : TLWID           ;
                                     const Name         : PChar           ) : Pointer        ;
    VIDDimension        : function  (      MeshInfo     : PLWMeshInfo     ;
                                           Data         : Pointer         ) : Integer        ;

    {
      Adjacent polygon information was added in 11.0
    }
    PntPolsNum          : function  (      MeshInfo     : PLWMeshInfo     ;
                                           PolyIndex    : UInt32          ;
                                           PointNum     : UInt32          ) : UInt32         ;
    PntPols             : function  (      MeshInfo     : PLWMeshInfo     ;
                                           PolyIndex    : UInt32          ;
                                           PointNum     : UInt32          ;
                                           Pols         : PPLWPol         ;
                                           MaxElements  : UInt32          ) : UInt32         ;
  end;

  {
    LightWave maintains a database which is essentially an image of
    all the LWO2 object files loaded into the application.  Each object
    contains some number of layers which can be scanned.  The functions
    for accessing this information is the "Scene Objects" global.

    NumObjects       returns the total number of objects in the scene.
                     These are the unique object files which are loaded,
                     which may have nothing to do with the animatable
                     items in the scene.

    Filename         returns the name of the source object file.  Objects
                     are indexed from 0 to numObjects - 1.

    UserName         returns the name of the object as seen by the user.
                     This is typically the base filename without path or
                     extension, or "Unnamed N" for unsaved objects.  These
                     are not guaranteed to be unique.

    RefName          returns an internal reference name for this object.
                     The reference name is guaranteed to be unique and
                     unchanging for the lifetime of the object.  This
                     string contains control characters so it cannot be
                     confused with a filename.

    MaxLayers        returns a value one greater than the largest index of
                     any existing layer.

    LayerExists      returns true if the layer with the given index exists.
                     Layers are indexed from 0 to maxLayers - 1.

    PivotPoint       fills in the position vector with the pivot point for
                     the given layer.

    LayerMesh        returns a mesh info structure for the given layer.  The
                     mesh will reference vertices in their rest positions.

    LayerName        returns the name string assigned to the layer, or null
                     if none.

    LayerVis         returns true if the layer is marked as visible.

    NumVMaps         returns the total number of vmaps in the scene with the
                     given type code.  A code of zero selects all vmaps of
                     every type.

    VMapName         returns the name of the vmap with the given index, from
                     0 to numVMaps - 1.

    VMapDim          returns the dimension of the vmap vector.

    VMapType         returns the type code of the vmap.  The index is into the
                     list of all vmaps given by numVMap with type code zero.

    MaxPointsPerPoly holds the maximum possible points that can be
                     used to define a polygon in LightWave.
  }
  PLWObjectFuncs = ^TLWObjectFuncs;
  TLWObjectFuncs = record
    NumObjects  : function                         : Integer    ;
    Filename    : function  (Obj     : Integer   ) : PChar      ;
    MaxLayers   : function  (Obj     : Integer   ) : Integer    ;
    LayerExists : function  (Obj     : Integer   ;
                             LNum    : Integer   ) : Integer    ;
    PivotPoint  : procedure (Obj     : Integer   ;
                             LNum    : Integer   ;
                             Pos     : TLWFVector) ;
    LayerMesh   : function  (Obj     : Integer   ;
                             LNum    : Integer   ) : PLWMeshInfo;

    NumVMaps    : function  (ID      : TLWID     ) : Integer    ;
    VMapName    : function  (ID      : TLWID     ;
                             InIndex : Integer   ) : PChar      ;
    VMapDim     : function  (ID      : TLWID     ;
                             InIndex : Integer   ) : Integer    ;
    VMapType    : function  (InIndex : Integer   ) : TLWID      ;

    LayerName   : function  (Obj     : Integer   ;
                             LNum    : Integer   ) : PChar      ;
    LayerVis    : function  (Obj     : Integer   ;
                             LNum    : Integer   ) : Integer    ;

    UserName    : function  (Obj     : Integer   ) : PChar      ;
    RefName     : function  (Obj     : Integer   ) : PChar      ;

    MaxPointsPerPoly : Integer;
  end;

{
  Polygon types are an extensible set of ID codes.  Some common ones
  are included here.
}
function LWPOLTYPE_FACE : TLWID;
function LWPOLTYPE_CURV : TLWID;
function LWPOLTYPE_PTCH : TLWID;
function LWPOLTYPE_SUBD : TLWID;
function LWPOLTYPE_MBAL : TLWID;
function LWPOLTYPE_BONE : TLWID;

{
  Polygon tags are indexed by an extensible set of ID codes.  Some
  common ones are included here.
}
function LWPTAG_SURF : TLWID;
function LWPTAG_PART : TLWID;
function LWPTAG_TXUV : TLWID;
function LWPTAG_COLR : TLWID;

{
 * VMAPs are identifed by an extensible set of ID codes.  Some common
 * ones are included here.
}
function LWVMAP_PICK : TLWID;
function LWVMAP_WGHT : TLWID;
function LWVMAP_MNVW : TLWID;
function LWVMAP_TXUV : TLWID;
function LWVMAP_MORF : TLWID;
function LWVMAP_SPOT : TLWID;
function LWVMAP_RGB  : TLWID;
function LWVMAP_RGBA : TLWID;
function LWVMAP_NORM : TLWID;

implementation

function LWPOLTYPE_FACE : TLWID; inline;
begin
  Result := LWID_('F','A','C','E');
end;
function LWPOLTYPE_CURV : TLWID; inline;
begin
  Result := LWID_('C','U','R','V');
end;
function LWPOLTYPE_PTCH : TLWID; inline;
begin
  Result := LWID_('P','T','C','H');
end;
function LWPOLTYPE_SUBD : TLWID; inline;
begin
  Result := LWID_('S','U','B','D');
end;
function LWPOLTYPE_MBAL : TLWID; inline;
begin
  Result := LWID_('M','B','A','L');
end;
function LWPOLTYPE_BONE : TLWID; inline;
begin
  Result := LWID_('B','O','N','E');
end;

function LWPTAG_SURF : TLWID; inline;
begin
  Result := LWID_('S','U','R','F');
end;
function LWPTAG_PART : TLWID; inline;
begin
  Result := LWID_('P','A','R','T');
end;
function LWPTAG_TXUV : TLWID; inline;
begin
  Result := LWID_('T','X','U','V');
end;
function LWPTAG_COLR : TLWID; inline;
begin
  Result := LWID_('C','O','L','R');
end;

function LWVMAP_PICK : TLWID; inline;
begin
  Result := LWID_('P','I','C','K');
end;
function LWVMAP_WGHT : TLWID; inline;
begin
  Result := LWID_('W','G','H','T');
end;
function LWVMAP_MNVW : TLWID; inline;
begin
  Result := LWID_('M','N','V','W');
end;
function LWVMAP_TXUV : TLWID; inline;
begin
  Result := LWID_('T','X','U','V');
end;
function LWVMAP_MORF : TLWID; inline;
begin
  Result := LWID_('M','O','R','F');
end;
function LWVMAP_SPOT : TLWID; inline;
begin
  Result := LWID_('S','P','O','T');
end;
function LWVMAP_RGB  : TLWID; inline;
begin
  Result := LWID_('R','G','B',' ');
end;
function LWVMAP_RGBA : TLWID; inline;
begin
  Result := LWID_('R','G','B','A');
end;
function LWVMAP_NORM : TLWID; inline;
begin
  Result := LWID_('N','O','R','M');
end;

end.

